<!DOCTYPE html>
<!--

// Copyright 2011 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

-->
<html>
<head>
<title></title>
<script src="../../../third_party/closure-library/closure/goog/base.js"></script>
<script>
goog.require('goog.testing.jsunit');
</script>
<script src="../../../src/traceur.js"></script>
</head>
<body>
<script>

var TreeWriter = traceur.outputgeneration.TreeWriter;
var ParseTreeTransformer = traceur.codegeneration.ParseTreeTransformer;
var ParseTreeType = traceur.syntax.trees.ParseTreeType;
var ParseTreeValidator = traceur.syntax.ParseTreeValidator;

var ParseTreeFactory = traceur.codegeneration.ParseTreeFactory;
var createBreakStatement = ParseTreeFactory.createBreakStatement;
var createContinueStatement = ParseTreeFactory.createContinueStatement;
var createCatchStatement = ParseTreeFactory.createCatchStatement;
var createIdentifierToken = ParseTreeFactory.createIdentifierToken;
var createCatch = ParseTreeFactory.createCatch;

function toTree(errorReporter, name, source) {
  var sourceFile = new traceur.syntax.SourceFile(name, source);
  var scanner = new traceur.syntax.Scanner(errorReporter, sourceFile);
  var parser = new traceur.syntax.Parser(errorReporter, scanner);
  var tree = parser.parseProgram();
  return tree;
}

function TestTransformer() {}

TestTransformer.prototype = traceur.createObject(
  ParseTreeTransformer.prototype, {
  
    transformBreakStatement: function(tree) {
      return createBreakStatement(tree.name);  // issue 75
    },

    transformContinueStatement: function(tree) {
      return createContinueStatement(tree.name);  // issue 75
    },
    
    transformCatch: function(tree) {
      var catchBody = this.transformAny(tree.catchBody);
      var binding = this.transformAny(tree.binding);
      
      return createCatch(binding.identifierToken, catchBody); // issue 71
    }
    
});

function oneTest(name, source) {
  var errors = [];

  var errorReporter = {
    reportError: function(position, message) {
      errors.push({position: String(position), message: message});
    }
  };

  var tree = toTree(errorReporter, name, source);
  var transformer = new TestTransformer();
  var output_tree = transformer.transformAny(tree);
  ParseTreeValidator.validate(output_tree);
  
  var output_source = traceur.outputgeneration.TreeWriter.write(output_tree);
  
  var input_value = eval(source);
  var output_value = eval(output_source);
  // console.log("output: "+output_value+" :\n "+output_source);
  assertEquals(input_value, output_value);
}

function testCreateBreakStatement() {
  var name = 'createBreakStatement';
  var source =
     'function f() {\n' +
     '  var a = 1;\n' +
     '  L1: while(a < 10) {\n' +
     '    while(a < 9) {\n' +
     '      a++;\n' +
     '      break L1;\n' +
     '    }\n' +
     '    a++;\n' +
     '  }\n' +
     '  return a;\n' +
     '}\n' +
     'f()\n';
  oneTest(name, source);
}

function testCreateContinueStatement() {
  var name = 'createContinueStatement';
  var source =
     'function f() {\n' +
     '  var a = 1, b = 1;\n' +
     '  L1: while(a < 10) {\n' +
     '    a++;\n' +
     '    while(b < a) {\n' +
     '      b++;\n' +
     '      continue L1;\n' +
     '    }\n' +
     '    b++;\n' +
     '  }\n' +
     '  return b;\n' +
     '}\n' +
     'f()\n';
  oneTest(name, source);
}

function testCreateCatch() {
  var name = 'createCatch';
  var source =
     'function f() {\n' +
     '  var a = 1;\n' +
     '  try {\n' +
     '    throw undefined;\n' +
     '  } catch (exc) {\n' +
     '    a = 2;\n' +
     '  }\n' + 
     '  return a;\n' +
     '}\n' +
     'f()\n';
  oneTest(name, source);
}
</script>
</body>
</html>
